package daily

import (
	"fmt"
	"sort"
	"time"
	"sync"

	"github.com/yqchilde/wxbot/engine/control"
	"github.com/yqchilde/wxbot/engine/pkg/log"
	"github.com/yqchilde/wxbot/engine/pkg/sqlite"
	"github.com/yqchilde/wxbot/engine/robot"
)

var (
	db            sqlite.DB
	hasAllGroups  bool
	WxId2NickName map[string]robot.ObjectInfo
	mutex         sync.Mutex
)

func init() {
	engine := control.Register("daily", &control.Options[*robot.Ctx]{
		Alias: "群聊日报",
		Help:  "统计群发言信息",
		DataFolder: "daily",
		OnCronjob: func(ctx *robot.Ctx) {
			t := time.Now()
			startTime := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
			startTime.Unix()
			t = time.Now().AddDate(0, 0, 1)
			endTime := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
			var chatRecords []ChatRecord
			result := db.Orm.Where("created_at > ? and created_at < ?", startTime, endTime).Find(&chatRecords)
			if result.Error != nil {
				log.Fatalf("get daily record failed: %v", result.Error)
				ctx.ReplyText("更新今日日报失败！")
				return
			} else {
				charRecordMap := make(map[string]map[string]int)
				for _, record := range chatRecords {
					if _, ok := charRecordMap[record.GroupId]; !ok {
						charRecordMap[record.GroupId] = make(map[string]int)
					}
					charRecordMap[record.GroupId][record.WxId] = charRecordMap[record.GroupId][record.WxId] + 1
				}
				for groupId, records := range charRecordMap {
					recordsSum := 0
					type KVPair struct {
						WxId      string
						RecordNum int
						NickName  string
					}
					tmpList := make([]KVPair, 0)

					for k, v := range records {
						recordsSum = recordsSum + v
						tmpList = append(tmpList, KVPair{WxId: k, RecordNum: v, NickName: k})
					}

					sort.Slice(tmpList, func(i, j int) bool {
						return tmpList[i].RecordNum < tmpList[j].RecordNum // 升序
					})

					for i := len(tmpList) - 1; i >= 0; i-- {
						if objectInfo, err := ctx.GetObjectInfo(tmpList[i].WxId); err == nil {
							tmpList[i].NickName = objectInfo.Nick
						}
					}
					message := fmt.Sprintf("【小助手日报提醒】\n今日有%d条消息\n\n活跃的门面担当是：", recordsSum)
					for i := len(tmpList) - 1; i >= 0 && i >= len(tmpList)-3; i-- {
						message = message + fmt.Sprintf("%s:%d，", tmpList[i].NickName, tmpList[i].RecordNum)
					}
					ctx.SendText(groupId, message)
				}
			}
		},
	})
	if err := sqlite.Open(engine.GetDataFolder()+"/daily.db", &db); err != nil {
		log.Fatalf("open sqlite db failed: %v", err)
	}
	if err := db.Create("group_infos", GroupInfo{}); err != nil {
		log.Fatalf("create group_infos table failed: %v", err)
	}
	if err := db.Create("chat_records", ChatRecord{}); err != nil {
		log.Fatalf("create chat_records table failed: %v", err)
	}

	WxId2NickName = make(map[string]robot.ObjectInfo)
	engine.OnRegex(".+", robot.OnlyGroupAndNotAtMe).SetBlock(true).Handle(func(ctx *robot.Ctx) {
		message := ctx.State["regex_matched"].([]string)[0]

		if _, ok := WxId2NickName[ctx.Event.FromWxId]; !ok {
			if objectInfo, err := ctx.GetObjectInfo(ctx.Event.FromWxId); err == nil {
				WxId2NickName[ctx.Event.FromWxId] = *objectInfo
			}
		}

		if !hasAllGroups {
			var groupsInfo []GroupInfo
			if allGroupsInfo, err := ctx.GetAllGroupsInfo(); err == nil {
				for _, groupInfo := range allGroupsInfo {
					groupsInfo = append(groupsInfo, GroupInfo{
						GroupId:      groupInfo.WxId,
						GroupName:    groupInfo.Nick,
						MemberNumber: groupInfo.MemberNum,
						WelcomeWords: "",
						IsDaily:      false,
						IsMonthly:    false,
					})
				}
			}
			if len(groupsInfo) > 0 {
				if result := db.Orm.Create(&groupsInfo); result.Error == nil {
					hasAllGroups = true
				} else {
					log.Fatalf("insert groupsInfo failed: %v", result.Error)
					return
				}
			}
		}
		mutex.Lock()
		if result := db.Orm.Create(&ChatRecord{
			GroupId: ctx.Event.FromGroup,
			WxId:    ctx.Event.FromWxId,
			Name:    WxId2NickName[ctx.Event.FromWxId].Nick,
			Message: message,
		}); result.Error != nil {
			log.Fatalf("insert a chatrecord failed: %v", result.Error)
		}
		mutex.Unlock()

	})
}

